home *** CD-ROM | disk | FTP | other *** search
- Listing 9.
-
- /* complain.cpp - message dictionary manager */
-
- #include <stdio.h>
- #ifdef __ZTC__
- #include <io.h> /* fseek() */
- #endif
- #include <stdlib.h>
- #include <string.h>
- #include "utils.hpp"
- #include "errmgr.hpp"
- #include "complain.hpp"
-
- /* a singly linked list of keys - should use hash */
- /* table for speed */
- class complain_ptr {
- public:
- complain_ptr(char *name,long offset,
- complain_ptr *head);
- ~complain_ptr(void);
- const char *errname(void) const
- { return _errname; }
- int complaint_text(const char *filename,
- char *line,int linelen);
- complain_ptr *next;
- private:
- char *_errname;
- long foffset;
- };
-
- /*************** class complaint_dict ***************/
-
- static complain_ptr *read_complaint_file(
- const char *filename);
-
- complaint_dict::complaint_dict(const char *filename)
- {
- /* constructor - remember file name, read all */
- /* messages and store offsets */
- _filename = newstring(filename);
- complain_table = read_complaint_file(_filename);
- }
-
- complaint_dict::~complaint_dict(void)
- {
- /* cleanup - delete all of the offset records */
- /* in the table. */
- complain_ptr *keyptr;
-
- free(_filename);
- while ((keyptr = complain_table) != 0) {
- complain_table = complain_table->next;
- delete keyptr;
- }
- }
-
- static complain_ptr *key(complain_ptr *complain_table,
- const char *name)
- {
- /* look for the key in the list of complain_ptr */
- /* objects. returns 0 if not found. */
- while (complain_table != 0 &&
- strcmp(name,complain_table->errname()))
- complain_table = complain_table->next;
- return complain_table;
- }
-
- int complaint_dict::key_defined(const char *name) const
- {
- /* return 1 if the key is defined here. */
- return key(complain_table,name) != 0;
- }
-
- int complaint_dict::complaint_text(const char *name,
- char *line,
- int linelen) const
- {
- /* retrieve the text for the named message and */
- /* store it in the buffer. returns 0 on failure. */
- complain_ptr *fmt;
-
- fmt = key(complain_table,name);
- if (fmt == 0) {
- sprintf(line,"Error key \"%s\" not found\n",
- key);
- return 0; /* failed */
- }
- if (fmt->complaint_text(_filename,line,linelen)) {
- sprintf(line,"Unable to re-read text for "
- "error key \"%s\"\n",key);
- return 0; /* failed */
- }
- return 1; /* all OK */
-
- } /* end of complaint_dict::complaint_text() */
-
- /************** local utility routines **************/
-
- static complain_ptr *read_complaint_file(
- const char *filename)
- {
- /* read all of the error keys in the complaint */
- /* file. */
- FILE *complaintfile;
- char line[512];
- long thisoffset;
- char *keyname,*p,*name;
- int all_ok = 1;
- complain_ptr *keyptr,*complain_table = 0;
-
- if ((complaintfile = fopen(filename,"r")) == 0) {
- err_mgr.error("Unable to read error text "
- "file %s\n",filename);
- return 0; /* OK to continue */
- }
-
- for (;;) { /* exit from within */
- /* remember the start of each line. */
- thisoffset = ftell(complaintfile);
- read_continued_line(complaintfile,line,
- sizeof(line));
- if (strlen(line) == 0) /* EOF? done */
- break;
-
- /* skip blank lines and comments. */
- keyname = p = line + skipblanks(line);
- if (!*p || *p == '\n' || *p == '#')
- continue;
- p += skip_ident(p); /* get key name */
- if (p == keyname) {
- err_mgr.warn("Missing error key in error "
- text file \"%s\":\n%s",
- filename,line);
- all_ok = 0;
- continue;
- }
-
- name = newstring(keyname,p - keyname);
- if (key(complain_table,name) != 0) {
- err_mgr.warn("Duplicate error key in "
- "error text file \"%s\":\n%s",
- filename,line);
- free(name);
- all_ok = 0;
- continue;
- }
- p += skipblanks(p);
- if (*p != ':') {
- err_mgr.warn("Missing ':' in error text "
- "file \"%s\":\n%s",
- filename,line);
- free(name);
- all_ok = 0;
- continue;
- }
-
- /* everything looks good - remember key. */
- keyptr = new complain_ptr(name,thisoffset,
- complain_table);
- complain_table = keyptr;
- }
-
- /* if problems were found ignore entire file. */
- fclose(complaintfile);
- if (!all_ok) {
- while ((keyptr = complain_table) != 0) {
- complain_table = complain_table->next;
- delete keyptr;
- }
- return 0;
- }
- return complain_table;
- }
-
- /**************** class complain_ptr ****************/
-
- complain_ptr::complain_ptr(char *name,long offset,
- complain_ptr *head)
- { /* constructor */
- /* add the new complain_ptr to the front of */
- /* the list. name is allocated for us; the */
- /* destructor must free it. */
- _errname = name;
- foffset = offset;
- next = head;
- }
-
- complain_ptr::~complain_ptr(void) /* destructor */
- {
- /* our caller cleans up the chain in next. */
- free(_errname);
- }
-
- int complain_ptr::complaint_text(
- const char *filename,
- char *line,int linelen)
- {
- /* re-read the message text for the key. */
- /* returns 1 on error (file has disappeared or */
- /* been edited). */
- FILE *complaintfile;
- char *keyname,*p;
- int newlen;
-
- line[0] = '\0'; /* clear old text */
- if ((complaintfile = fopen(filename,"r")) == 0)
- return 1;
- if (fseek(complaintfile,foffset,SEEK_SET)) {
- fclose(complaintfile);
- return 1;
- }
- read_continued_line(complaintfile,line,linelen);
- fclose(complaintfile);
-
- /* make sure we still have the same key! (file */
- /* may have been edited) */
- keyname = p = line + skipblanks(line);
- p += skip_ident(p);
- if (p == keyname ||
- strncmp(keyname,_errname,strlen(_errname)))
- return 1;
- p += skipblanks(p);
- if (*p != ':')
- return 1;
- ++p; /* skip ':', */
- p += skipblanks(p); /* leading blanks */
-
- /* shift everything over to cover the key. */
- newlen = strlen(p);
- memmove(line,p,newlen + 1);
- return 0; /* all OK */
- }